﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TfsGiggle.Core;
using System.ServiceModel;
using Microsoft.VisualStudio.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using System.ServiceModel.Channels;
using System.Diagnostics;

namespace TfsGiggle.Search
{
    /// <summary>
    /// Helper class for a powershell client
    /// </summary>
    public static class PowerShellClient
    {
        static string GetSearchConnectionUri(Binding binding)
        {
            var dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.10.0");
            if (dte2 == null)
            {
                Trace.TraceError("GetSearchConnectionUri:Could not get handle to Visual Studio");
                return null;
            }
            var tfsExt = dte2.GetObject(TfsGiggleSearchPackage.TeamFoundationServerExtService) as TeamFoundationServerExt;
            if (tfsExt == null || tfsExt.ActiveProjectContext == null || string.IsNullOrWhiteSpace(tfsExt.ActiveProjectContext.DomainUri))
            {
                Trace.TraceError("GetSearchConnectionUri:Could not get a TeamFoundationServerExt object");
                return null;
            }
            var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsExt.ActiveProjectContext.DomainUri));
            if (tfs == null)
            {
                Trace.TraceError("GetSearchConnectionUri:Could not get tfs with the url:{0}", tfsExt.ActiveProjectContext.DomainUri);
                return null;
            }
            tfs.EnsureAuthenticated();
            var uri = Client.GetRegisteredTfsGiggleUri(tfs);
            var newUrl = string.Format("{0}://{1}:{2}/Search", binding.Scheme, uri.DnsSafeHost, uri.Port + 1);
            var searchConnectionUri = new Uri(newUrl);
            return searchConnectionUri.AbsoluteUri;
        }

        /// <summary>
        /// Execute a search and return the result
        /// </summary>
        /// <param name="userQuery"></param>
        /// <returns></returns>
        public static QueryResultDTO Search(string userQuery)
        {
            var binding = Client.GetBinding();
            var searchConnection = GetSearchConnectionUri(binding);
            var address = new EndpointAddress(searchConnection);
            using (var factory = new ChannelFactory<ISearch>(binding, address))
            {
                var client = factory.CreateChannel();
                var result = client.Query(userQuery);
                ((IChannel)client).Close();
                return result;
            }
        }

        /// <summary>
        /// Add the changeset for the specified teamprojectcollection to the index. 
        /// See example on how to find the teamprojectcollectionid
        /// <example>
        /// $tfs = [Microsoft.TeamFoundation.Client.TfsConfigurationServerFactory]::GetConfigurationServer("http://localhost:8080/tfs")
        /// $collectionService = $tfs.GetService([Microsoft.TeamFoundation.Framework.Client.ITeamProjectCollectionService])
        /// $collectionService.GetCollections()|%{ $_.Name + ": " + $_.Id }
        /// </example>
        /// </summary>
        /// <param name="teamProjectCollectionId"></param>
        /// <param name="changesetId"></param>
        public static void AddChangeset(string teamProjectCollectionId, int changesetId)
        {
            var binding = Client.GetBinding();
            var searchConnection = GetSearchConnectionUri(binding);
            var address = new EndpointAddress(searchConnection);
            using (var factory = new ChannelFactory<ISearch>(binding, address))
            {
                var client = factory.CreateChannel();
                client.AddChangeset(teamProjectCollectionId, changesetId);
                ((IChannel)client).Close();
            }
        }
    }
}